package lectores;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.HashMap;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.poifs.filesystem.POIFSFileSystem;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;

public class LectorCondicionesBProduccion {

  //Objetos para la lectura del 
  private File archivoExcel;
  private Workbook libroCondiciones;
  private String insertCamposQuery = "INSERT INTO condiciones (ag_prom, id_agente, id_promotor, inicio_vig, ppa, ppd, ppp, rechazos, enero, febrero, marzo, "
          + "abril, mayo, junio, julio, agosto, septiembre, octubre, noviembre, diciembre, mes_trimestre, adicional1, adicional2) VALUES ";
  private Statement st;
  //Lleva un registro de los agentes a calcular para refinar la lectura a la base de datos de convenios
  //Esto se hace con un hashmap que contiene los ids y aparte indica si su calculo es mes o trimestre
  public HashMap<String, Integer> agProm_MesTrim;

  public LectorCondicionesBProduccion(File archivoExcel) throws FileNotFoundException, IOException, SQLException, ExcelMalFormadoException {
    this.archivoExcel = archivoExcel;
    cargaArchivo();
  }

  private void cargaArchivo() throws FileNotFoundException, IOException, SQLException, ExcelMalFormadoException {
    //Se inicializa el hashmap de los agentes y promotores
    agProm_MesTrim = new HashMap<String, Integer>();

    //Se carga el libro Excel Workbook
    InputStream inp = new FileInputStream(this.archivoExcel);
    if (archivoExcel.getName().toLowerCase().endsWith(".xls")) {
      libroCondiciones = new HSSFWorkbook(new POIFSFileSystem(inp));
    } else {
      libroCondiciones = new XSSFWorkbook(inp);
    }

    //Se carga los datos a la base
    st = cargaBaseDeDatos();
    creaTablaCondiciones(st);
    llenaTablaCondiciones(st);
    libroCondiciones = null;
    this.st.close();
  }

  private Statement cargaBaseDeDatos() throws SQLException, ExcelMalFormadoException {
    try {
      Class.forName("org.hsqldb.jdbcDriver");
    } catch (ClassNotFoundException ex) {
      Logger.getLogger(LectorCondicionesBProduccion.class.getName()).log(Level.SEVERE, null, ex);
    }

    Connection conexion = DriverManager.getConnection("jdbc:hsqldb:bonos_produccion", "sa", "");
    return conexion.createStatement();
  }

  private void creaTablaCondiciones(Statement st) throws SQLException {
    String sql = null;
    st.executeUpdate("DROP TABLE IF EXISTS condiciones");
    sql = "CREATE TABLE condiciones (ag_prom VARCHAR(10), id_agente INTEGER, id_promotor INTEGER, meta_d double, "
            + "inicio_vig VARCHAR(10),ppa double,ppd double,ppp double,rechazos double, enero double, febrero double, "
            + "marzo double, abril double, mayo double, junio double, julio double, agosto double, septiembre double, "
            + "octubre double, noviembre double, diciembre double, meta_anual double, mes_trimestre INTEGER, adicional1 INTEGER, adicional2 INTEGER)";
    st.executeUpdate(sql);
  }

  public void llenaTablaCondiciones(Statement st) throws SQLException, ExcelMalFormadoException {
    Sheet hojaCondiciones = (Sheet) libroCondiciones.getSheetAt(0);
    verificaEncabezados(hojaCondiciones);

    int indiceEmpiezaRenglonDatos = 1;
    Row renglonActual;
    for (int i = indiceEmpiezaRenglonDatos; i <= hojaCondiciones.getLastRowNum(); i++) {
      renglonActual = hojaCondiciones.getRow(i);
      int celCount = -1;

      String tipo = "";
      int clave = 0;
      int promotoria = 0;
      double porc_bon_autos = 0;
      double porc_bon_dañ = 0;
      double porc_bon_pers = 0;
      double rechazos = 0;
      double[] metas_meses = new double[12];
      int mesTrimestre = 0;
      int idAdicional1 = -1;
      int idAdicional2 = -1;

      try {
        celCount = 0;
        tipo = renglonActual.getCell(celCount).getStringCellValue();

        if (!tipo.equalsIgnoreCase("promotor") && !tipo.equalsIgnoreCase("agente")) {
          throw new ExcelMalFormadoException(i, 0, ExcelMalFormadoException.CONDICIONES, archivoExcel);
        }

        celCount = 1;
        try {
          clave = (int) renglonActual.getCell(celCount).getNumericCellValue();
        } catch (Exception ex) {
          throw new ExcelMalFormadoException(i, 1, ExcelMalFormadoException.CONDICIONES, archivoExcel);
        }
        if (clave < 0) {
          throw new ExcelMalFormadoException(i, 1, ExcelMalFormadoException.CONDICIONES, archivoExcel);
        }
        celCount = 2;
        try {
          promotoria = (int) renglonActual.getCell(celCount).getNumericCellValue();
        } catch (Exception ex) {
          throw new ExcelMalFormadoException(i, 2, ExcelMalFormadoException.CONDICIONES, archivoExcel);
        }
        if (promotoria < 0) {
          throw new ExcelMalFormadoException(i, 2, ExcelMalFormadoException.CONDICIONES, archivoExcel);
        }
        celCount = 5;
        try {
          porc_bon_autos = renglonActual.getCell(celCount).getNumericCellValue();
        } catch (Exception ex) {
          throw new ExcelMalFormadoException(i, 5, ExcelMalFormadoException.CONDICIONES, archivoExcel);
        }
        celCount = 6;
        try {
          porc_bon_dañ = renglonActual.getCell(celCount).getNumericCellValue();
        } catch (Exception ex) {
          throw new ExcelMalFormadoException(i, 6, ExcelMalFormadoException.CONDICIONES, archivoExcel);
        }
        celCount = 7;
        try {
          porc_bon_pers = renglonActual.getCell(celCount).getNumericCellValue();
        } catch (Exception ex) {
          throw new ExcelMalFormadoException(i, 7, ExcelMalFormadoException.CONDICIONES, archivoExcel);
        }
        celCount = 8;
        try {
          rechazos = renglonActual.getCell(celCount).getNumericCellValue();
        } catch (Exception ex) {
          throw new ExcelMalFormadoException(i, 8, ExcelMalFormadoException.CONDICIONES, archivoExcel);
        }

        celCount = 9;
        for (int j = 0; j < metas_meses.length; j++) {
          try {
            metas_meses[j] = renglonActual.getCell(celCount).getNumericCellValue();
          } catch (Exception ex) {
            throw new ExcelMalFormadoException(i, 9 + j, ExcelMalFormadoException.CONDICIONES, archivoExcel);
          }
          celCount++;
        }

        celCount = 22;
        try {
          mesTrimestre = renglonActual.getCell(celCount) != null && renglonActual.getCell(celCount).getStringCellValue().equals("T") ? 1 : 0;
        } catch (Exception ex) {
          throw new ExcelMalFormadoException(i, 22, ExcelMalFormadoException.CONDICIONES, archivoExcel);
        }
        celCount = 23;

        int idAdicionalExcel = renglonActual.getCell(celCount) != null ? (int) (renglonActual.getCell(celCount).getNumericCellValue()) : 0;
        try {
          if (idAdicionalExcel != 0) {
            idAdicional1 = idAdicionalExcel;
          }
        } catch (Exception ex) {
          throw new ExcelMalFormadoException(i, 23, ExcelMalFormadoException.CONDICIONES, archivoExcel);
        }

        celCount = 24;
        idAdicionalExcel = renglonActual.getCell(celCount) != null ? (int) (renglonActual.getCell(celCount).getNumericCellValue()) : 0;
        try {
          if (idAdicionalExcel != 0) {
            idAdicional2 = idAdicionalExcel;
          }
        } catch (Exception ex) {
          throw new ExcelMalFormadoException(i, 24, ExcelMalFormadoException.CONDICIONES, archivoExcel);
        }
      } catch (IllegalStateException ise) {
        throw new ExcelMalFormadoException(i, celCount, ExcelMalFormadoException.TIPO_INESPERADO, archivoExcel);
      }
      String query = insertaEnCondiciones(tipo, "" + clave, "" + promotoria, "null", porc_bon_autos, porc_bon_dañ, porc_bon_pers, rechazos,
              metas_meses[0], metas_meses[1], metas_meses[2], metas_meses[3], metas_meses[4], metas_meses[5], metas_meses[6],
              metas_meses[7], metas_meses[8], metas_meses[9], metas_meses[10], metas_meses[11], mesTrimestre, idAdicional1, idAdicional2);
      st.executeUpdate(query);
      agProm_MesTrim.put("" + promotoria + "." + clave + "." + idAdicional1 + "." + idAdicional2, mesTrimestre);
    }
  }

  public String insertaEnCondiciones(String ag_prom, String id_agente, String idPromo, String inicio_vig, double ppa, double ppd, double ppp,
          double rechazos, double enero, double febrero, double marzo, double abril, double mayo, double junio, double julio,
          double agosto, double septiembre, double octubre, double noviembre, double diciembre, int mesTrimestre, int idAdicional1, int idAdicional2) {
    String query = "'" + ag_prom + "', " + id_agente + "," + idPromo + "," + inicio_vig + "," + ppa + "," + ppd + "," + ppp + ","
            + rechazos + "," + enero + "," + febrero + "," + marzo + "," + abril + "," + mayo + "," + junio
            + "," + julio + "," + agosto + "," + septiembre + "," + octubre + "," + noviembre + "," + diciembre + "," + mesTrimestre + "," + idAdicional1 + "," + idAdicional2;
    return insertCamposQuery + query;
  }

  private void verificaEncabezados(Sheet hojaCondiciones) throws ExcelMalFormadoException {
    boolean not_valido = hojaCondiciones == null || hojaCondiciones.getRow(0).getLastCellNum() != 25;
    if (not_valido) {
      throw new ExcelMalFormadoException(ExcelMalFormadoException.FALTA_COLUMNA, archivoExcel);
    }
  }

  public HashMap<String, Integer> getMesTrim() {
    return agProm_MesTrim;
  }
}